﻿'use strict'
let mysql = require("mysql");
let colors = require('colors');
let dbConfig = require("../../main/appConfig").mysqlConfig;

let mysql_err = "";
let queryFormat = function (query, values) {
  if (!values) return query;
  return query.replace(/\:(\w+)/g, function (txt, key) {
    if (values.hasOwnProperty(key)) {
      return this.escape(values[key]);
    }
    return txt;
  }.bind(this));
};

let log_mysql = function (sql, vals) {
  let fullSql = "";
  if (!vals) {
    vals = {};
  }
  fullSql = "mysql:    " + sql + "\n" + JSON.stringify(vals);


  fullSql = (  fullSql.replace(/\n/ig, "\n          "));
  console.log(fullSql);
}
//
// var connection;
// function handleDisconnect() {
//   connection = mysql.createConnection(dbConfig);
//   connection.connect(function(err) {
//     if(err) {
//       console.log("进行断线重连：" + new Date());
//       setTimeout(handleDisconnect, 2000);   //2秒重连一次
//       return;
//     }
//   });
//   connection.on('error', function(err) {
//     console.log('db error', err);
//     if(err.code === 'PROTOCOL_CONNECTION_LOST') {
//       handleDisconnect();
//     } else {
//       throw err;
//     }
//   });
// }
// handleDisconnect();

//记得最后  conn.release();
let getConn = async() => {
  try {
    let pool = mysql.createPool(dbConfig);
    if (!pool) return console.error("mysql pool Error:" + err);

    return new Promise(function (resolve, reject) {
      return pool.getConnection(function (err, conn) {
        if (err) {
          console.error(err);
          resolve(null);
          return;
        }
        resolve(conn);
      });
    });
  }
  catch (err) {
    console.error("mysql connecte Error:" + err);
    throw err;
    return;
  }
}

//自动释放连接
let mysql_find = async function (sql, vals) {
  if (!sql) return;
  log_mysql(sql, vals);

  let db = await getConn();
  if (!db) return console.error("获取连接失败");


  if (sql.startsWith("select")) {
    db.config.queryFormat = queryFormat;
  }

  try {
    //return  pool.query(sql,vals);
    return new Promise(function (resolve, reject) {
      return db.query(
        sql,
        vals, function (err, res) {
          db.release();
          if (err) {
            console.error(err);
            mysql_err = err;
            reject(err);
            return;
          }
          resolve(res);
        });
    });
  }
  catch (err) {
    db.release();
    console.error("mysql Error:" + err);

    throw err;
    return;
  }
}

let mysql_findOne = async function (sql, vals) {
  let result = await mysql_find(sql, vals);
  return result && result[0];
}
//插入数据，可以是多条，但以第一条数据的列为标准
let mysql_insert = async function (table, data) {
  let datas = [];
  if (Array.isArray(data)) {
    datas = data;
  }
  else {
    datas.push(data);
  }

  if (!datas.length) {
    mysql_err = "找不到要插入的数据";
    return {affectedRows: 0, msg: mysql_err};
  }

  let keys = [];
  for (let k in datas[0]) {
    keys.push(k);
  }
  let vals_temp = "(" + keys.map(it => "?").join(",") + ")";
  let sql = "insert into `" + table + "` (" + keys.map(it => "`" + it + "`").join(",") + ") values " + datas.map(it => vals_temp);
  let vals = [];
  for (let item of datas) {
    vals = vals.concat(keys.map(key => item[key]));
  }

  return await mysql_find(sql, vals);
}

let mysql_update = async function (table, setData, whereData) {
  let keys = [];
  for (let k in setData) {
    keys.push(k);
  }

  let whereKeys = [];
  for (let k in whereData) {
    whereKeys.push(k);
  }

  let sql = "update `" + table + "` set " + keys.map(it => "`" + it + "`=?").join(",") + " where " + whereKeys.map(it => "`" + it + "`=?").join(" and ");
  return await mysql_find(sql, keys.map(it => setData[it]).concat(whereKeys.map(it => whereData[it])));
}

exports.find = mysql_find;
exports.findOne = mysql_findOne;
exports.exec = mysql_find;
exports.insert = mysql_insert;
exports.update = mysql_update;
exports.error = function () {
  return mysql_err;
}
